/**
 * 线编辑插件1,本编辑插件采用中心点显示marker点的方式，也就是百度和autonavi官方的行为
 * 
 * 点的形式应该有两种，一种是线的中点，一种是线的两端.
 * 		有个问题？他们之间关系应该怎样确立呢？是直接让顶点有联系，还是通过middle点来建立联系？
 * 		先采用通过middle点来建立关系试试效果
 * 创建一种链表形式，来维护各个产生的marker点，以middleMarker这样可以保证代码可操作性
 * 小功能划分：
 * 1.产生middleMarker点,为（middleMarker点建立连接应该属于单独的功能）
 * 1.1 创建普通点 
 * 2.更新marker数组序列
 * 3.middleMarker点转变顶点，也就是普通marker点（或者采用消除原有点，产生新的点）
 * 4.建立顶点监听函数，（onclick，拖拽）
 * 5.建立middleMarker点的监听函数（onclick，拖拽）
 * 6.消除顶点，同时建立middle点，
 * 7.update 折线点，用来重新绘制折线,重新绘制线，需要调用折线的setPath方法，所以必须要建立好path和marker的对应关系
 */

(function(){
	MMap.PolylineEditor=MMap.Class({
		_version:1.0,
		//构造函数,初始化map对象，折线数组，以及额外参数
		/* 额外参数包括marker的icon图片
		 */
		initialize:function(polyline,opt){
			function init(){
				opt=opt||{};
				this.polyline=polyline||{},this.mapobj=this.polyline._map;
				//为所有添加的marker生成唯一的id
				this.mMarkerIndex=1;
				this.polyline._edit=!0;
				this.synId="_polylineEditor_"+Math.floor(Math.random()*1000);
				this.opt={
						vertexIcon:opt["vertexIcon"]||this.mapobj._client+"Images/point.png",
						middleIcon:opt["middleIcon"]||this.mapobj._client+"Images/point_m.png"
				}
			}
			this.flag=(typeof polyline!=="undefined"&&polyline instanceof MMap.Polyline&&typeof polyline["_edit"]==="undefined"
			);
			this.flag&&this.mEnv(init);
		},
		mBindMiddleMarkerEvent:function(marker){
			//标准t代表是onclick还是拖拽
			var t=0,obj=this;
			//中间点的拖拽开始注册方法
			function s(event){
				obj.mapobj.bind(marker,"dragging",i,"plugin");	
				obj.mapobj.bind(marker,"mouseup",e,"plugin");
			}
			//中间点拖拽时注册方法
			function i(event){
				t=1;
				var num=1;
				if(typeof marker.toVertexMarkerIndex==="undefined"){
					var index=marker.pre._index+1;
					marker.toVertexMarkerIndex=index;
					num=0;
				}
				obj.mUpdatePath(marker.toVertexMarkerIndex,num,event.lnglat);
				obj.mUpdatePolyline();
			}
			//mouseup注册事件
			function e(event){
				obj.mapobj.unbind(marker,"dragging",i);
				obj.mapobj.unbind(marker,"mouseup",arguments.callee);
				if(t==0){return}
				//拖拽结束后
					t=0;
					obj.mapobj.unbind(marker,"mousedown",s);
					obj.mMTV(marker);
					obj.markers.splice(marker.toVertexMarkerIndex,0,marker);
					delete marker.toVertexMarkerIndex;
					var m1=obj.mCmiddleMarker(marker.pre,marker);
					var m2=obj.mCmiddleMarker(marker,marker.next);
					obj.mapobj.addOverlays(m1);
					obj.mapobj.addOverlays(m2);
					obj.middleMarkers.splice(marker._index,1,m1,m2);
					obj.mUpdateMiddleMarkerIndex();
					obj.mUpdateMarkerIndex();
			}
			this.mapobj.bind(marker,"mousedown",s,"plugin");
		},
		/*
		 * middle点与marker点转换
		 */
		mMTV:function(marker){
			this.mBindVertexMarkerEvent(marker);
			marker.setIcon(this.opt["vertexIcon"]);
		},
		/*
		 * 更新折线
		 */
		mUpdatePolyline:function(){
			this.polyline.setPath(this.path);
		},
		/*
		 * @param {Object} pre
		 * @param {Object} next
		 * @return {TypeName} 
		 */
		mUpdatePath:function(position,num,lnglat){
			this.path.splice(position,num,lnglat);
		},
		/*
		 * 创建中间middle点
		 */
		mCmiddleMarker:function(left,right){
			var m,obj=this;
			m=obj.mBuildMarker(obj.mCalMiddleLngLat(left.getPosition(),right.getPosition()),2);
			obj.mBindMiddleMarkerEvent(m);
			obj.mRelate(left,m);
			obj.mRelate(m,right);
			return m;
		},
		/*
		 * 计算两个经纬度的中点(目前采取最简单的方案...)
		 * @param {Object} pre
		 * @param {Object} next
		 * @return {TypeName} 
		 */
		mCalMiddleLngLat:function(pre,next){
			return !!pre&&!!next&&new MMap.LngLat((pre.lng+next.lng)/2.0,(pre.lat+next.lat)/2.0);
		},
		/*
		 * 创建顶点的marker点
		 * @param {Object} point
		 * @return {TypeName} 
		 */
		mBindVertexMarkerEvent:function(marker){
			var obj=this,t=0;
			//拖拽注册时间
			function s(event){
				obj.mapobj.bind(marker,"dragging",i,"plugin");
				obj.mapobj.bind(marker,"mouseup",e,"plugin");
				marker.pre&&(marker.leftMarkerLnglat=marker.pre.pre.getPosition());
				marker.next&&(marker.rightMarkerLnglat=marker.next.next.getPosition());
			}
			//因为gis的dragstart事件，如果鼠标按下去没有马上触发移动的话，是不会进行dragstart事件的所以采用mousedonw事件
			function i(event){
				t=1;
				var lnglat=event.lnglat;
				obj.mUpdatePath(marker._index,1,lnglat);
				//更新折线
				obj.mUpdatePolyline();
				//更新marker点关联的middle点,但是由于效率问题，
				//marker对象的getPosition方法会计算lnglat，每次都计算的话，肯定会有效率问题,所以采用其他方案
				marker.pre&&marker.pre.setPosition(obj.mCalMiddleLngLat(lnglat,marker.leftMarkerLnglat));
				marker.next&&marker.next.setPosition(obj.mCalMiddleLngLat(lnglat,marker.rightMarkerLnglat));
			}
			function e(event){
				//拖拽结束后，删除属性
				marker.pre&&(delete marker.leftMarkerLnglat);
				marker.next&&(delete marker.rightMarkerLnglat);
				obj.mapobj.unbind(marker,"dragging",i);
				obj.mapobj.unbind(marker,"mouseup",arguments.callee);
				//代表是click，删除点
				t?t=0:obj.mRemoveMarker(marker);
			}
			obj.mapobj.bind(marker,"mousedown",s,"plugin");
		},
		/*
		 * 消除出marker
		 * 1.消除该marker点在path中的lnglat，消除其在markers中。
		 * 2.判断是否存在左边点。如果不存在，代表就是左边第一个点
		 */
		mRemoveMarker:function(marker){
			//只有两个点时，不允许消除点
			if(this.markers.length<3) return;
			function rm(mm){
				obj.middleMarkers.splice(mm._index,1);
				obj.mapobj.removeOverlays(mm.id);
				obj.mUpdateMiddleMarkerIndex();
			}
			var left,right,temp,l=!0,r=!0,obj=this;
			!marker.pre?(l=!1,delete marker.next.next.pre,rm(marker.next)):(left=marker.pre.pre,rm(marker.pre));
			!marker.next?(r=!1,delete marker.pre.pre.next,rm(marker.pre)):(right=marker.next.next,rm(marker.next));
			//添加中间点
			l&&r&&(temp=obj.mCmiddleMarker(left, right),obj.mapobj.addOverlays(temp));
			obj.path.splice(marker._index,1);
			obj.markers.splice(marker._index,1);
			obj.mUpdatePolyline();
			obj.mUpdateMarkerIndex();
			//为了解决，直接删除点，会造成点击事件处理异常的问题
			setTimeout(function(){
				obj.mapobj.removeOverlays(marker.id);
			},1);
		},
		/*
		 * 该方法用于建立两个marker点的关系
		 * @param {Object} pre marker
		 * @param {Object} next  marker
		 */
		mRelate:function(pre,next){
			!!pre&&(pre.next=next);
			!!next&&(next.pre=pre);
		},
		
		/*
		 * edit方法，打开折线编辑
		 * 如果曾经编辑过的话，那么该方法不会再次初始化markers，而是直接使用上次的markers数组，优化效率
		 */
		edit:function(){
			var obj=this;
			obj.flag&&(typeof obj.markers ==="undefined" && obj.mInitMarkers(),obj.mSetVisible());
		},
		mBuildMarker:function(position,category){
			var category=category||1;
			var opt={};
			switch(category){
				case 1:
					opt.icon=this.opt["vertexIcon"];
					break;
				case 2:
					opt.icon=this.opt["vertexIcon"];
					break;
				default:
					opt.icon=this.opt["vertexIcon"];
					break;
			}
			return this.mCreateMarker(position,opt);
		},
		/*
		 *  该方法用于建立maker对象
		 * @param {Object} point  point点
		 * @param {Object} opt  marker的opt
		 * @return {TypeName} 
		 */
		mCreateMarker:function(position,opt){
			var markerOption={
				draggable:true,
				icon:opt["icon"],
				position:position,
				//真奇怪这里，marker点竟然和折线的点的位置不在同一个位置，必须得加上这个偏移量
				offset:{x:-6,y:-10},
				id:this.synId+(this.mMarkerIndex++).toString(36)
			}
			return new MMap.Marker(markerOption);
		},
		//抽离出来的方法
		mv:function(){
			return function(markers,bool){
				var obj=this;
				function s(){
					for(var index in obj[markers])
						obj[markers][index].setVisible(bool);
				}
				!!obj[markers]&&s();
			}
		},
		//执行环境作用域
		mEnv:function(fn){
			return typeof fn==="function"&&fn.apply(this,Array.prototype.slice.call(arguments,1));
		},
		//4个简单方法
		mSetVertexMarkerVisible:function(){
			this.mEnv(this.mv(),"markers",!0);
		},
		mSetMiddleMarkerVisible:function(){
			this.mEnv(this.mv(),"middleMarkers",!0);
		},
		mSetVertexMarkerUnvisible:function(){
			this.mEnv(this.mv(),"markers",!1);
		},
		mSetMiddleMarkerUnvisible:function(){
			this.mEnv(this.mv(),"middleMarkers",!1);
		},
		mSetVisible:function(){
			this.mSetMiddleMarkerVisible();
			this.mSetVertexMarkerVisible();
		},
		/*
		 * 初始化markers，用属性polyline的折线信息初始化marker点,middleMarker点
		 */
		mInitMarkers:function(){
			this.markers=[];
			this.middleMarkers=[];
			var obj=this;
			function initMarkers(){
				for(var point in obj.path){
					var vertexMarker=obj.mBuildMarker(obj.path[point]);
					obj.mBindVertexMarkerEvent(vertexMarker);
					obj.markers.push(vertexMarker);
				}
				obj.mapobj.addOverlays(obj.markers);
			}
			function initMiddleMarkers(){
				for(var index=0;index<obj.markers.length-1;index++){
					var m=obj.mCmiddleMarker(obj.markers[index], obj.markers[index+1]);
					obj.middleMarkers.push(m);
				}
				obj.mapobj.addOverlays(obj.middleMarkers);
			}
			obj.path=this.polyline.getPath(),initMarkers(),initMiddleMarkers(),this.mUpdateMiddleMarkerIndex(),this.mUpdateMarkerIndex();
			
		},
		
		/*
		 * 抽离出来的方法
		 */
		mu:function(){
			return function(markers){
				for(var index=0,length=this[markers].length;index<length;index++){
					this[markers][index]._index=index;
				}
			}
		},
		/*
		 * 更新markers数组序号
		 */
		mUpdateMarkerIndex:function(){
			this.mEnv(this.mu(),"markers");
		},
		/*
		 * 更新middlemarker数组的序号
		 * @memberOf {TypeName} 
		 */
		mUpdateMiddleMarkerIndex:function(){
			this.mEnv(this.mu(),"middleMarkers");
		},
		/*
		 * close方法，关闭折线编辑，但是并未取消与折线关联
		 */
		close:function(){
			this.mSetVertexMarkerUnvisible();
			this.mSetMiddleMarkerUnvisible();
		},
		/* 改方法为了节省资源，当彻底不需要编辑折线时，
		 * 可调用此方法，掉用完后，可以销毁此对象，如果直接delete该对象，则导致原折线不可在编辑等。
		 * cancle方法，彻底取消与折线的关联,
		 */
		cancle:function(){
			typeof this.polyline!=="undefined"&&delete this.polyline["_edit"];
			typeof this.markers!=="undefined"&&this.close();
			for(v in this){
				this.hasOwnProperty(v)&&delete this[v];
			}
		},
		//返回marker点，
		getVertexMarkers:function(){
			return this["markers"]||[];
		},
		/*
		 * 返回middleMarkers点
		 */
		getMiddleMarkers:function(){
			return this["middleMarkers"]||[];
		}
	})
;})()